package com.misyi.designpattern.templatemethod;

/**
 * 模板方法模式
 *
 * @author licong
 * @date 2021-09-10 下午10:29
 */
public class TemplateMethodPatternDemo {

    public static void main(String[] args) {
        AbstractDiscountCalculator abstractDiscountCalculator1 = new AbstractDiscountCalculator1();
        AbstractDiscountCalculator abstractDiscountCalculator2 = new AbstractDiscountCalculator2();
        AbstractDiscountCalculator abstractDiscountCalculator3 = new AbstractDiscountCalculator3();
        abstractDiscountCalculator1.calculate();
        abstractDiscountCalculator2.calculate();
        abstractDiscountCalculator3.calculate();
    }

    public interface DiscountCalculator {
        void calculate();
    }


    public abstract static class AbstractDiscountCalculator implements DiscountCalculator {

        @Override
        public void calculate() {
            commonCalculate();
            // 提供开放拓展的钩子方法
            hookMethod();
            // 子类特殊的计算逻辑
            childCalculate();
        }

        private void commonCalculate() {
            System.out.println("通用的计算逻辑");
        }

        protected void hookMethod() {
            System.out.println("父类的钩子方法");
        }

        protected abstract void childCalculate();
    }


    public static class AbstractDiscountCalculator1 extends AbstractDiscountCalculator {

        @Override
        public void hookMethod() {
            System.out.println("优惠计算器 1 的钩子实现, 开放拓展修改");
        }

        @Override
        protected void childCalculate() {
            System.out.println("优惠计算器 1 的特殊执行逻辑");
        }
    }

    public static class AbstractDiscountCalculator2 extends AbstractDiscountCalculator {

        @Override
        protected void childCalculate() {
            System.out.println("优惠计算器 2 的特殊执行逻辑");
        }
    }

    public static class AbstractDiscountCalculator3 extends AbstractDiscountCalculator {

        @Override
        protected void childCalculate() {
            System.out.println("优惠计算器 3 的特殊执行逻辑");
        }
    }


}
